#-*- coding:utf-8 -*-

# json模块
import json
# 随机数模块
import random
# 时间模块
import time, os
# 高性能数组模块
import numpy as np
from vno import *
from vno_path import *
from vno_data import *
# from scipy.spatial import distance
# 遗传算法模块inspyred
from inspyred import ec
from inspyred import swarm
from inspyred.ec import terminators
from inspyred.ec import observers
from inspyred.ec import analysis
import inspyred
import itertools

# 表格美化打印输出模块
from prettytable import PrettyTable

# 适应值曲线绘制模块
import ea_utils
from creat_plot import creat_plot

import multiprocessing  # 多进程


#从词典中获以key获取value
def get_dict_value(kwargs, key, value):
    if key in kwargs:
        return kwargs[key]
    else:
        return value

#若给定的目录不存在则创建一个目录
def creat_dir(dirs):
    if not os.path.exists(dirs):
        os.makedirs(dirs)

#网络解算
def each_vno(vnet,edge_id,delta_r = 0.0):
    t0 = time.time()
    dg = vnet.graph()
    ret = vno(vnet)
    if not ret:
        print u'[适应值计算-分支编号(%d)风阻变化:(%lf)]通风网络解算失败,程序退出!'%(edge_id,delta_r)
        return
    new_q = [ee['q'] for ee in dg.es if not is_zero_edge(ee)]  # 解算风量
    return  new_q

#具体问题类，用于修改适应函数和参数设定
class Problem():
    def __init__(self,args):
        self.lb = args.get('lb',0)
        self.ub = args.get('ub',1)
        self.bounder = ec.Bounder(self.lb, self.ub)
        self.var_types = args['var_types']
        self.var_num = len(self.var_types)
        self.X0 = args['X0']
        self.vnet = args['vnet']
        self.edge_ids = args['edge_ids']

    # 返回变量的上下限
    def bounder(self):
        return ec.Bounder(self.lb, self.ub)
        
    # 随机生成一个在上下限范围内的编码
    # random -- 随机数生成器对象
    def rand(self, rng):
        lub = [rng.uniform(self.lb[i], self.ub[i]) for i in xrange(self.var_num)]
        edge_id = rng.choice(self.edge_ids)
        lub[0] = edge_id
        return lub
    
    # 将个体编码(取值范围[0,1])解码为"真实变量"(取值范围[lb, ub])
    # 数学计算公式: f=(b-a)*x+a, 其中x范围[0,1], f范围[a, b]
    def decode(self, X):
        # return [self.g(i, x) for i,x in enumerate(X)]
        d_x = []
        for i,x in enumerate(X):
            if self.var_types[i] == 0:
                d_x.append(int(x))
            else:
                d_x.append(x)
        return d_x

    def fitness(self, X):
        # 染色体进行解码
        X1 = self.decode(X)
        n = X1[0]
        # 排除风井
        if n not in self.edge_ids:
            return 10
        delta_r = X1[n]
        dg = self.vnet.graph()
        e = dg.es[n-1]
        r0 = e['r']
        e['r'] = r0+ delta_r
        q = each_vno(self.vnet,n,delta_r)
        e['r'] = r0
        if q is None:
            if delta_r > 0:
                self.ub[n] = delta_r
            else:
                self.lb[n] = delta_r
            ec.Bounder(self.lb, self.ub)
            return 10
        Q = self.X0
        if len(Q) != len(q):
            print u'%d分支风阻为0'%n
            return 10
        QQ = np.array(Q)
        qq = np.array(q)
        distance= np.sqrt(np.sum(np.square(QQ-qq)))
        return distance
    
    def generator(self, random, args):
        return self.rand(random)
        
    def evaluator(self, candidates, args):
        fitness = []
        for X in candidates:
            # 将浮点数四舍五入,强制转换为0和1,并计算个体的适应值
            score = self.fitness(X)
            #添加到列表
            fitness.append(score)
        return fitness

#[终止函数]平均值小于一定精度时终止
def _my_avg_terminator(population, num_generations, num_evaluations, args):
    tolerance = args.setdefault('tolerance', 0.001)
    pop_fit = [x.fitness for x in population]
    avg_fit = sum(pop_fit) / float(len(population))
    best_fit = max(pop_fit)
    if (best_fit - avg_fit) < tolerance:
        return True
    if num_generations > args['max_generations']:
        return True
    return False

#[终止函数]10代以内所有适应值之间的差都满足精度精度时终止
def _my_terminator(population, num_generations, num_evaluations, args):
    if num_generations > args['max_generations']:
        return True
    previous_best = args.setdefault('previous_best', None)
    current_best = max(population).fitness
    if previous_best is None or abs(previous_best - current_best) > 0.001:
        args['previous_best'] = current_best
        args['generation_count'] = 0
        return False
    else:
        if args['generation_count'] >= 10:
            return True
        else:
            args['generation_count'] += 1
            return False    
    return False

# 自定义终止条件
# 根据指定的类型来选择终止条件函数
def my_terminator(terminator_type):
    TerminatorDict = {
        # 按进化代数终止: 表示进化多少代之后就终止,无论是否达到最优,也不考虑算法是否收敛
        1:terminators.generation_termination,
        # 按适应值计算次数终止: 表示适应值计算多少次后就就终止,无论是否达到最优,也不考虑算法是否收敛
        2:terminators.evaluation_termination,
        # 按种群的平均适应值终止: 表示种群的平均适应值连续多少代没有显著变化就终止,因为进化过程已经收敛或者假收敛了
        3:terminators.average_fitness_termination,
        4:_my_terminator,
        5:terminators.no_improvement_termination,
        6:_my_avg_terminator
    }
    if not (terminator_type in TerminatorDict):
        terminator_type = 1
    return TerminatorDict[terminator_type]

#种群生成
def generate_rastrigin(random, args):
    return args['problem'].generator(random, args)

#适应值计算
def evaluate_rastrigin(candidates, args):
    return args['problem'].evaluator(candidates, args)
    
# 遗传算法主框架
def runGA(args):
    #随机数初始化
    rng = random.Random()
    rng.seed(int(time.time()))
    algo = args.get('algo', 1)
    es = None
    if algo == 1:
        # 遗传算法
        es = ec.GA(rng)
    elif algo == 2:
        # 粒子群算法
        es = swarm.PSO(rng)
        es.topology = swarm.topologies.ring_topology
    elif algo == 3:
        # 模拟退火算法
        es = ec.SA(rng)
    elif algo == 4:
        # 差分进化算法
        es = ec.DEA(rng)
    elif algo == 5:
        # 进化策略算法
        es = ec.ES(rng)    
    else:
        # 默认采用遗传算法
        es = ec.GA(rng)

    #设置终止条件
    es.terminator = my_terminator(args['terminator'])
    es.observer = observers.file_observer
    # 新建种群数据记录文件
    stat_file = open(args['stat_file'], 'w')
    ind_file = open(args['ind_file'], 'w')   
    problem = Problem(args)
    final_pop = es.evolve(generator=generate_rastrigin, 
                          evaluator=inspyred.ec.evaluators.parallel_evaluation_mp,
                          mp_evaluator=evaluate_rastrigin, 
                          mp_nprocs=3,
                          pop_size=args.get('popsize', 10), 
                          bounder=inspyred.ec.Bounder(args['lb'],args['ub']),
                          maximize=False,
                          max_evaluations = args.get('max_evaluations', 1200),   # 最大适应值计算次数
                          max_generations = args.get('max_generations', 20),
                          statistics_file = stat_file, 
                          individuals_file = ind_file, 
                          problem = problem,
                          # 遗传算法GA参数
                          mutation_rate = args.get('mutation_rate',0.015),       # 变异率
                          cross_rate =  args.get('cross_rate',0.75),            # 交叉率
                          # 粒子群算法PSO参数
                          neighborhood_size =  args.get('neighborhood_size',5),  # 邻域范围
                        #   差分进化
                          crossover_rate = 0.75)

    # 关闭种群数据记录文件
    stat_file.close()
    ind_file.close()
    final_pop.sort(reverse = True)
    return final_pop[0].candidate

#读取拓扑数据并建立通风网络
def read_vnet_datas():
    ga_config = read_json_file(GA_CONFIG_FILE)
    # 1. 准备通风网络数据
    graph_datas = read_graph_datas(ga_config['graph_datas'])    
    struct_Ids = graph_datas['struct_eID']
    shaft_ids = graph_datas['shaft_eID']
    # 2. 构造通风网络,读取并设置相关数据
    vnet = VentNetwork()
    if not build_network(graph_datas, vnet.graph()):
        print u'\t-->构造通风网络失败!!!'
        return
    # 4. 添加虚拟源汇,将网络变成单一源汇通风网络
    vnet.addVirtualST()
    # print u'\t-->构造通风网络成功!!!'
    return vnet,struct_Ids,shaft_ids

#已知风阻变化网络解算结果(返回值应是监测到风量)
def init_q(vnet, edge_id,delta_r):
    if vnet is None:
        return None
    dg = vnet.graph()
    edges = dg.es
    e = edges[edge_id-1]
    r0 = e['r']
    e['r'] = delta_r + r0
    if not vno(vnet):
        print u'[初始化]通风网络解算失败,程序退出!'
        e['r'] = r0
        return None
    e['r'] = r0
    Q = [ee['q'] for ee in edges if not is_zero_edge(ee)]
    return Q

#初始化参数
def init_config(vnet,int_range,float_ranges,edge_ids):
    lb = [int_range[0]]
    ub = [int_range[1]]
    vt = [0]
    for l in np.array(float_ranges)[:,0]:
        lb.append(l)
    for u in np.array(float_ranges)[:,1]:
        vt.append(1)
        ub.append(u)
    # 参数设置
    config = {
        #---------------- 自定义参数: 变量及范围  -----------------#
        # 变量类型(0-整数,1-实数) 
        "var_types":vt,    
        # 下限(数组中的每一位代表一个变量的下限)
        "lb":lb,
        # 上限(数组中的每一位代表一个变量的上限)
        "ub":ub,
        "vnet":vnet,
        # 分支编号（去掉风井的分支）
        "edge_ids":edge_ids,
        #---------------- 自定义参数: 距离度量方法及终止条件  -----------------#
        "algo": 1,                      # 算法选择
                                        #   1. 遗传算法GA
                                        #   2. 粒子群算法PSO
                                        #   3. 模拟退火算法SA
                                        #   4. 差分进化算法DEA
                                        #   5. 进化策略ES
                
        "terminator": 4,                # 终止条件(1-表示按最大进化代数终止迭代)
                                        #   1. 按最大进化代数终止迭代
                                        #   2. 按最大适应值计算次数终止迭代
                                        #   3. 按种群平均适应值收敛终止迭代

        #---------------- 进化算法通用参数(遗传、粒子群、蚁群、模拟退火等)  -----------------#
        "popsize": 500,                  # 种群规模
        "max_generations": 1000,        # 最大进化代数
        "max_evaluations": 1000,        # 最大适应值计算次数(暂未使用)

        #---------------- 遗传算法GA参数 --------------------#
        "cross_rate": 0.9,             # 交叉率(默认1.0)
        "mutation_rate": 0.5,         # 变异率(默认0.1)
        # "num_selected": 50              # 被选择的个体数(默认等于种群规模popsize)
        # "num_crossover_points": 1       # 交叉点个数(默认单点交叉,等于1)
        # "num_elites": 0                 # 启用精英策略,保留n个最优个体到下一代(默认0)

        #---------------- 粒子群算法PSO参数 -----------------#
        "neighborhood_size": 5,          # 邻域范围
        # "cognitive_rate": 2.1           # the rate at which the particle’s current position influences its movement (default 2.1)
        # "social_rate": 2.1              # the rate at which the particle’s neighbors influence its movement (default 2.1)
        # "inertia": 0.5                  # the inertia constant to be used in the particle updating (default 0.5)
        
        #---------------- 模拟退火算法SA参数 ------------------#
        # "temperature": 100,             # the initial temperature
        # "cooling_rate": 0.618,           # a real-valued coefficient in the range (0, 1) by which the temperature should be reduced
        # "mutation_rate": 0.5,            # the rate at which mutation is performed (default 0.1)
        # "gaussian_mean": 0,              # the mean used in the Gaussian function (default 0)
        # "gaussian_stdev": 1             # the standard deviation used in the Gaussian function (default 1)

        #---------------- 差分进化算法DEA参数 ------------------#
        # "num_selected": 2               # the number of individuals to be selected (default 2)
        # "tournament_size": 2            # the tournament size (default 2)
        # "crossover_rate": 1.0           # the rate at which crossover is performed (default 1.0)
        # "mutation_rate": 0.1            # the rate at which mutation is performed (default 0.1)
        # "gaussian_mean": 0              # the mean used in the Gaussian function (default 0)
        # "gaussian_stdev": 1             # the standard deviation used in the Gaussian function (default 1)
    }
    return config

#创建初始化参数
def creat_config(config,edge_id,delta_r,measure_q,out_dir):
    out_stat_dir = out_dir + '/stat/'
    out_ind_dir = out_dir + '/ind/'
    creat_dir(out_stat_dir)
    creat_dir(out_ind_dir)

    config['stat_file'] = ''.join([out_stat_dir,'id[%d]-'%edge_id,'delta_r[%.3f]-'%delta_r,"stat.csv"])
    config['ind_file'] = ''.join([out_ind_dir,'id[%d]-'%edge_id,'delta_r[%.3f]-'%delta_r,"ind.csv"])# 每一代的进化参数记录
    # 定义问题对象并添加到config词典中
    # 个体生成、适应值计算均由该对象负责,详见Problem类的定义
    config['X0'] = measure_q
    # config['problem'] = Problem(config['lb'], config['ub'], config['var_types'], measure_q, config['vnet'],config['edge_ids'])
    return config

def ea_test(config):
    start = time.time()
    # 遗传算法计算得到"最优"个体
    best_X = runGA(config)
    # 结束时间
    stop = time.time()
    print u'计算耗时:', "%.1fs" % (stop-start)
    return best_X

def sortListByOne(elem):
    return elem[0]

#图形绘制
def plotting(out_ret):
    plot_dir = './out/plot/'
    creat_dir(plot_dir)
    min_value = 0.1
    # sorted_ret = out_ret
    # sorted_ret.sort(key=sortListByOne)
    datas = np.array(out_ret)
    right_hat = [rh for rh in out_ret if rh[0] == rh[1]]
    accuracy1 = '%.2f%%'%(1.0*len(right_hat)/len(datas)*100)
    right_hat2 = [rh for rh in out_ret if abs(rh[2] - rh[3]) < min_value]
    accuracy2 = '%.2f%%'%(1.0*len(right_hat2)/len(datas)*100)
    accuracy = []
    accuracy.append(accuracy1)
    accuracy.append(accuracy2)    
    # sorted_datas = np.array(sorted_ret)
    ea_utils.plot2(datas,plot_dir,u'全部分支',accuracy)
    edge_num = len(set(datas[:,0].tolist()))
    for i in xrange(1,edge_num+1):
        y = [d for d in out_ret if d[0]==i]
        datas = np.array(y)
        if len(datas) <= 0:
            continue
        right_hat = [rh for rh in y if rh[0] == rh[1]]
        accuracy1 = '%.2f%%'%(1.0*len(right_hat)/len(datas)*100)
        right_hat2 = [rh for rh in y if abs(rh[2] - rh[3]) < min_value]
        accuracy2 = '%.2f%%'%(1.0*len(right_hat2)/len(datas)*100)
        accuracy = []
        accuracy.append(accuracy1)
        accuracy.append(accuracy2)    
        ea_utils.plot2(datas,plot_dir,'e%d'%i,accuracy)

#检查上下限是否会导致无法解算
def vno_cheak(c,edge_id,edges,vnet):
    if vnet is None:
        return 0
    e = edges[edge_id-1]
    r0 = e['r']
    e['r'] = c*r0 + r0
    while(not vno(vnet)):
        if c < 0:
            c = random.uniform(c,0)
        else:
            c = random.uniform(0,c)
        e['r'] = c*r0 + r0
        # print c,e['r']
    e['r'] = r0
    return c

#初始化上下限参数
def init_lub_params(args):
    print('正在计算范围...')
    struct_ids = args.get('struct_ids',[])
    shaft_ids = args.get('shaft_ids',[])
    # 2. 构造通风网络,读取并设置相关数据
    vnet = args.get('vnet',None)
    edges = args.get('edges',[])
    R = args.get('R',[])
    ids = args.get('ids',[])
    float_ranges = []
    for edge_id in ids:
        c0 = -1
        c1 = 1
        if edge_id in struct_ids:
            c0 = -0.99
            c1 = 1.1
        elif edge_id in shaft_ids:
            c0 = 0
            c1 = 0
        else:
            c0 = -0.1
            c1 = 100
        lc = vno_cheak(c0,edge_id,edges,vnet)
        uc = vno_cheak(c1,edge_id,edges,vnet)
        float_range = [R[edge_id-1]*lc, uc*R[edge_id-1]]
        # print edge_id,c0,c1
        # print float_range
        float_ranges.append(float_range)
    dir_name = './out/lub/%d/'%len(ids)
    creat_dir(dir_name)
    np.savetxt(dir_name+'foat_range.txt',float_ranges,fmt="%.4f",delimiter='\t',header="lb\tub",comments="")
    return float_ranges


def init_lub_ranges(recreat_lub = False):
    ga_config = read_json_file(GA_CONFIG_FILE)
    # 1. 准备通风网络数据
    graph_datas = read_graph_datas(ga_config['graph_datas'])    
    struct_ids = graph_datas['struct_eID']
    shaft_ids = graph_datas['shaft_eID']
    # 2. 构造通风网络,读取并设置相关数据
    vnet = VentNetwork()
    if not build_network(graph_datas, vnet.graph()):
        print u'\t-->构造通风网络失败!!!'
        return
    # 4. 添加虚拟源汇,将网络变成单一源汇通风网络
    vnet.addVirtualST()
    dg = vnet.graph()
    edges = dg.es
    R = [ee['r'] for ee in edges if not is_zero_edge(ee)]
    ids = [int(ee['id']) for ee in edges if not is_zero_edge(ee)]
    # edge_ids = random.sample(range(1,len(edges)+1),len(edges))
    edge_ids = [e_id for e_id in ids if e_id not in shaft_ids]
    min_id = min(edge_ids)
    max_id = max(edge_ids)

    int_range = [min_id,max_id]
    float_ranges = []
    file_name = './out/lub/%d/foat_range.txt'%len(ids)
    if (recreat_lub or not os.path.exists(file_name)):
        args={'struct_ids':struct_ids,'shaft_ids':shaft_ids,'vnet':vnet,'edges':edges,'R':R,'ids':ids}
        float_ranges = init_lub_params(args)
    else:
        float_ranges = np.loadtxt(file_name,dtype=None,skiprows=1)
    return {'int_range':int_range,'float_ranges':float_ranges,'vnet':vnet,'edge_ids':edge_ids}

def creat_delta_r(change_count = 200):
    creat_dir('./out')
    init_ret = init_lub_ranges()
    float_ranges = init_ret['float_ranges']
    out_ret = []
    edge_ids = init_ret['edge_ids']
    for edge_id in edge_ids:
        print(u'计算分支号为%s的数据...'%edge_id)
        float_range = float_ranges[edge_id-1]
        for _ in xrange(0,change_count):
            delta_r = random.uniform(float_range[0],float_range[1])
            # while( abs(delta_r) < 0.01):
            #     delta_r = random.uniform(float_range[0],float_range[1])
            out_ret.append([edge_id,delta_r])
    dir_name = u'./out/%d分支/'%len(float_ranges)
    creat_dir(dir_name)
    np.savetxt(dir_name+'id_delta_r.txt',out_ret,fmt="%d\t%.4f",delimiter='\t',header="edge_id\tdelta_r",comments="")
    return edge_ids

def split_delta_rs(change_count = 200,num_edges = 10):
    id_delta_r = np.loadtxt(u'./out/%d分支/id_delta_r.txt'%num_edges,dtype=None,skiprows=1)
    root_dir = u'./out/%d分支/each_id_rs/'%num_edges
    creat_dir(root_dir)
    i = 0
    delta_rs = []
    for id_r in id_delta_r:
        i += 1
        delta_rs.append(id_r[1])
        if(i == change_count):
            file_name = root_dir+'e%d.txt'%id_r[0]
            np.savetxt(file_name,delta_rs,fmt="%.4f")
            i = 0
            delta_rs = []
        
def caculating(config, id_delta_r,vnet,out_dir):
    out_ret = []
    for id_r in id_delta_r:
        edge_id = int(id_r[0])
        delta_r = id_r[1]
        Q = init_q(vnet,edge_id,delta_r)
        if Q is None:
            break
        config = creat_config(config,edge_id,delta_r,Q,out_dir)
        for j in xrange(0,1):
            best_X = ea_test(config)
            n = int(best_X[0])
            each_out = [edge_id,n,delta_r,best_X[n]]
            # file_name = ''.join(['./out/','id[%d]-'%edge_id,'delta_r[%.3f]-'%delta_r,'best_id[%d]-'%n,'best_deta_r[%.3f]-'%best_X[n],'ea.png'])
            # 绘制图形
            # ea_utils.plot(config['stat_file'], file_name, False)
            out_ret.append(each_out)
    return out_ret

def read_delta_r_byid(ids,num_edges,id_delta_r):
    ret_id_r = []
    for id_r in id_delta_r:
        edge_id = int(id_r[0])
        delta_r = id_r[1]
        if edge_id in ids:
            ret_id_r.append([edge_id,delta_r])
    return ret_id_r

def comp_cacul(out_dir, algos = {'ga':1,'pso':2,'dea':4,'es':5},id_delta_r = None, ids = None):
    print(u'正在计算...')
    init_ret = init_lub_ranges()
    float_ranges = init_ret['float_ranges']
    int_range = init_ret['int_range']
    vnet = init_ret['vnet']
    edge_ids = init_ret['edge_ids']
    if id_delta_r is None:
        id_delta_r = np.loadtxt(u'./out/%d分支/id_delta_r.txt'%len(float_ranges),dtype=None,skiprows=1)
    if ids is not None:
        id_delta_r = read_delta_r_byid(ids,len(float_ranges),id_delta_r)
    config = init_config(vnet,int_range,float_ranges,edge_ids)
    for k,algo in algos.items():
        config['algo'] = algo
        ret_dir = out_dir+'%s'%k
        creat_dir(ret_dir)
        out_ret = caculating(config, id_delta_r,vnet,ret_dir)
        if not out_ret:
            print u'无结果'
            return
        file_name = ret_dir + '/out_ret.txt'
        np.savetxt(file_name,out_ret,fmt="%d\t%d\t%.3f\t%.3f",delimiter='\t',header="edge_id\tbest_id\tdelta_r\tbetst_r",comments="")

def comp_cacul_time(out_dir, max_itr,algos = {'ga':1,'pso':2,'dea':4,'es':5}, id_delta_r = None, ids = None):
    print(u'正在计算...')
    init_ret = init_lub_ranges()
    float_ranges = init_ret['float_ranges']
    int_range = init_ret['int_range']
    vnet = init_ret['vnet']
    edge_ids = init_ret['edge_ids']
    if id_delta_r is None:
        id_delta_r = np.loadtxt(u'./out/%d分支/id_delta_r.txt'%len(float_ranges),dtype=None,skiprows=1)
    if ids is not None:
        id_delta_r = read_delta_r_byid(ids,1,id_delta_r)
    config = init_config(vnet,int_range,float_ranges,edge_ids)
    for k,algo in algos.items():
        t = 0
        ret_dir = out_dir+'%s'%k
        creat_dir(ret_dir)
        file_name = ret_dir + '/time_out.txt'
        t_out = []
        for i in xrange(0,max_itr):
            start = time.time()
            config['algo'] = algo
            out_ret = caculating(config, [id_delta_r[i]],vnet,ret_dir)
            if not out_ret:
                print u'无结果'
                continue
            stop = time.time()
            t0 = (stop-start)
            t += t0
            t_out.append([i+1,t])
        np.savetxt(file_name,t_out,fmt="%d\t%.3f",delimiter='\t',comments="")
   
def get_init_params():
    ga_config = read_json_file(GA_CONFIG_FILE)
    # 1. 准备通风网络数据
    graph_datas = read_graph_datas(ga_config['graph_datas'])    
    struct_ids = graph_datas['struct_eID']
    shaft_ids = graph_datas['shaft_eID']
    # 2. 构造通风网络,读取并设置相关数据
    vnet = VentNetwork()
    if not build_network(graph_datas, vnet.graph()):
        print u'\t-->构造通风网络失败!!!'
        return None
    # 4. 添加虚拟源汇,将网络变成单一源汇通风网络
    vnet.addVirtualST()
    if vnet is None:
        return None
    if not vno(vnet):
        print u'[初始化]通风网络解算失败,程序退出!'
        return None
    dg = vnet.graph()
    edges = dg.es
    Q = [ee['q'] for ee in edges if not is_zero_edge(ee)]
    ids = [ee['id'] for ee in edges if not is_zero_edge(ee)]
    rs = [ee['r'] for ee in edges if not is_zero_edge(ee)]
    vnet.delVirtualST()
    return ids, Q, rs


# 主函数
def main():
    # init_lub_ranges(True)
    # creat_delta_r()
    
    # edge_ids = [42]
    # init_ret = init_lub_ranges()
    # float_ranges = init_ret['float_ranges']
    # for _id in edge_ids:
    #     id_delta_r = []
    #     for _ in xrange(0,20):
    #         _r = random.uniform(float_ranges[_id-1][0],float_ranges[_id-1][1])
    #         id_delta_r.append([_id,_r])
    #     dir_name = u'./out/100分支/id-%d/'%_id
    #     comp_cacul(dir_name,algos = {'dea':4}, id_delta_r=id_delta_r)

    # *************
    # edge_ids = [9]
    # init_ret = init_lub_ranges()
    # float_ranges = init_ret['float_ranges']
    # for _id in edge_ids:
    #     id_delta_r = []
    #     for _ in xrange(0,10):
    #         _r = random.uniform(float_ranges[_id-1][0],float_ranges[_id-1][1])
    #         id_delta_r.append([_id,_r])
    #     dir_name = u'./out/100分支/id-%d/'%_id
    #     comp_cacul(dir_name, algos = {'ga':1}, id_delta_r=id_delta_r)
    # *************

    edge_ids = [9]
    init_ret = init_lub_ranges()
    float_ranges = init_ret['float_ranges']
    for _id in edge_ids:
        id_delta_r = []
        for _ in xrange(0,10):
            _r = random.uniform(float_ranges[_id-1][0],float_ranges[_id-1][1])
            id_delta_r.append([_id,_r])
        dir_name = u'./out/xxx/'
        comp_cacul(dir_name, id_delta_r=id_delta_r)

    # comp_cacul_time(u'./out/time/',50, ids=[5])

    # ids, Q, rs = get_init_params()
    # ret = []
    # for _id, _q, _r in zip(ids, Q, rs):
    #     ret.append([int(_id),_r,_q])
    # print ret
    # np.savetxt(u'./out/10分支/init_q.txt', ret, fmt="%d\t%.4f\t%.2f",delimiter='\t',comments="")
    # comp_cacul(u'./out/10分支/')
    # split_delta_rs()
    # change_repeatly()
    # change_once()
    # creat_plot('./out/ga/out_ret.txt')

if __name__ == "__main__":
    # 主函数入口
    start = time.time()
    main()
    stop = time.time()
    print u'总耗时:', "%.1fs" % (stop-start)
